package utils

import (
	"gitee.com/shijun123456/kcgin"
	cv3 "github.com/asim/go-micro/plugins/registry/consul/v3"
	"github.com/asim/go-micro/v3/registry"
	"github.com/asim/go-micro/v3/selector"
)

//consul 的工具库
//registry仓库信息
type ConsulClient struct {
	register Registry //仓库信息
	node     Node
	service  Service
}

//默认考客户端信息
func DefaultConsulClient() *ConsulClient {
	return &ConsulClient{
		register: Registry{
			Address: kcgin.AppConfig.String("consul.address"),
		},
		node: Node{
			Id:      kcgin.AppConfig.String("appname"), //以appname 名称作为节点的id信息
			Address: kcgin.AppConfig.String("node.address"),
		},
		service: Service{
			Name:    kcgin.AppConfig.String("servicename"),
			Version: kcgin.AppConfig.String("app.version"),
		},
	}
}
func NewConsulClient(register Registry, node Node, service Service) *ConsulClient {
	return &ConsulClient{register: register, node: node, service: service}
}

//服务注册
func (c *ConsulClient) ServiceRegisterByMicro() error {
	consuleReg := cv3.NewRegistry(
		registry.Addrs(c.register.Address),
	)
	//注册器封装
	//node 封装
	node := &registry.Node{}
	node.Address = c.node.Address
	node.Id = c.node.Id
	node.Metadata = c.node.Metedata

	// service
	service := new(registry.Service)
	service.Name = c.service.Name
	service.Version = c.service.Version
	service.Nodes = append(service.Nodes, node)

	err := consuleReg.Register(service)
	if err != nil {
		return err
	}
	return nil
}

type Registry struct {
	Address string
}
type Node struct {
	Address  string
	Id       string
	Metedata map[string]string
}
type Service struct {
	Name    string
	Version string
}

func NewService(name string, version string) *Service {
	return &Service{Name: name, Version: version}
}

func NewNode(address string, id string) *Node {
	return &Node{Address: address, Id: id, Metedata: make(map[string]string)}
}
func NewRegistry(address string) *Registry {
	return &Registry{Address: address}
}

//加权轮训处理
//返回地址信息
func (c *ConsulClient) ServiceFindByMicro(servicename string) (string, error) {
	consulReg := cv3.NewRegistry(
		registry.Addrs(c.register.Address),
	) //新建一个祖册地址
	getService, err := consulReg.GetService(servicename) //使用服务获取服务
	if err != nil {
		return "", err
	}
	next := selector.RoundRobin(getService)
	node, err := next()
	if err != nil {
		return "", err
	}
	return node.Address, nil
}
func (c *ConsulClient) ServiceUnRegisterByMicro() error {
	consulReg := cv3.NewRegistry(
		registry.Addrs(c.register.Address),
	) //新建一个祖册地址
	node := &registry.Node{}
	node.Address = c.node.Address
	node.Id = c.node.Id
	node.Metadata = c.node.Metedata

	service := new(registry.Service)
	service.Name = c.service.Name
	service.Version = c.service.Version
	service.Nodes = append(service.Nodes, node)

	return consulReg.Deregister(service)
}
